﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace UnvApi
{
    public class TimeFormatter
    {
        #region 获取当天/指定时间

        /// <summary>
        /// 获取当前时间DateTime对象
        /// </summary>
        /// <returns></returns>
        public static DateTime getCurrentDateTime()
        {
            return DateTime.Now;
        }
        /// <summary>
        /// 获取当前日期时间字符串，默认格式"yyyy/MM/dd HH:mm:ss"
        /// </summary>
        /// <returns></returns>
        public static string getCurrentDateString()
        {
            return DateTime.Now.ToString();
        }
        /// <summary>
        /// 获取当前日期时间字符串，指定格式format，如"yyyy-MM-dd HH:mm:ss"
        /// </summary>
        /// <param name="format"></param>
        /// <returns></returns>
        public static string getCurrentDateString(string format)
        {
            return DateTime.Now.ToString(format);
        }
        /// <summary>
        /// 获取当前秒级时间戳（UTC时间），北京时间需要加上8小时的秒数（8*60*60）
        /// </summary>
        /// <returns></returns>
        public static long getCurrentTimestamp()
        {
            //DateTime转秒级时间戳(转为UTC时间，然后于1970年1月1日0点相减，得到的秒数)
            long unixTimestampSeconds = (long)(DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
            return unixTimestampSeconds;
        }
        /// <summary>
        /// 获取指定日期（0点整）的DateTime对象
        /// </summary>
        /// <param name="year">年</param>
        /// <param name="month">月</param>
        /// <param name="day">日</param>
        /// <returns></returns>
        public static DateTime getCertainDatetime(int year, int month, int day)
        {
            return new DateTime(year, month, day);
        }
        /// <summary>
        /// 获取指定时间的DateTime对象
        /// </summary>
        /// <param name="year">年</param>
        /// <param name="month">月</param>
        /// <param name="day">日</param>
        /// <param name="hours">时</param>
        /// <param name="minutes">分</param>
        /// <param name="seconds">秒</param>
        /// <returns></returns>
        public static DateTime getCertainDatetime(int year, int month, int day, int hours, int minutes, int seconds)
        {
            return new DateTime(year, month, day, hours, minutes, seconds);
        }

        #endregion

        #region 日期格式转换

        /// <summary>
        /// 字符串转DateTime（字符串如果不符合ISO 6801格式，会抛出异常）
        /// </summary>
        /// <param name="timeString"></param>
        /// <returns></returns>
        public static DateTime stringToDatetime(string timeString)
        {
            
            DateTime result = DateTime.Parse(timeString);
            return result;
        }
        /// <summary>
        /// 将特定格式的字符串转为DateTime，format示例"yyyy-MM-dd HH:mm:ss"（实际字符串于传入格式不符会抛出异常）
        /// </summary>
        /// <param name="timeString"></param>
        /// <param name="format"></param>
        /// <returns></returns>
        public static DateTime stringToDatetime(string timeString, string format)
        {
            DateTime result = DateTime.ParseExact(timeString, format, CultureInfo.InvariantCulture);
            return result;
        }

        /// <summary>
        /// DateTime转特定格式字符串，format示例"yyyy-MM-dd HH:mm:ss"
        /// </summary>
        /// <param name="datetime"></param>
        /// <param name="format"></param>
        /// <returns></returns>
        public static string datetimeToString(DateTime datetime, string format)
        {
            string result = datetime.ToString(format);
            return result;
        }
        /// <summary>
        /// 日期字符串转时间戳（输入当地时间，转为UTC时间，再转时间戳）
        /// </summary>
        /// <param name="timeString"></param>
        /// <param name="format"></param>
        /// <returns></returns>
        public static long stringToTimestamp(string timeString, string format)
        {
            DateTime datetime = DateTime.ParseExact(timeString, format, CultureInfo.InvariantCulture);
            long result = (long)(datetime.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
            return result;
        }
        /// <summary>
        /// 传入UTC时间戳、时间格式，转为北京时间字符串
        /// </summary>
        /// <param name="timestamp"></param>
        /// <param name="format"></param>
        /// <returns></returns>
        public static string timestampToString(long timestamp, string format)
        {
            DateTime dateTime = DateTimeOffset.FromUnixTimeSeconds(timestamp + 8 * 60 * 60).DateTime;
            string result = dateTime.ToString(format);
            return result;
        }
        /// <summary>
        /// 传入UTC时间戳、时间格式、与UTC时间偏移小时数（如北京时间应该传入8），转为对应的时间字符串
        /// </summary>
        /// <param name="timestamp"></param>
        /// <param name="format"></param>
        /// <param name="hoursOff"></param>
        /// <returns></returns>
        public static string timestampToString(long timestamp, string format, int hoursOff)
        {
            DateTime dateTime = DateTimeOffset.FromUnixTimeSeconds(timestamp + hoursOff * 60 * 60).DateTime;
            string result = dateTime.ToString(format);
            return result;
        }

        #endregion

        #region 日期计算

        /// <summary>
        /// 增加年、月、日（对应位置传入负数即可减去对应数值）
        /// </summary>
        /// <param name="dateTime">计算前的日期时间对象</param>
        /// <param name="years">年</param>
        /// <param name="months">月</param>
        /// <param name="days">日</param>
        /// <returns></returns>
        public static DateTime calculate(DateTime dateTime, int years, int months, int days)
        {
            DateTime result = new DateTime(dateTime.Year, dateTime.Month, dateTime.Day);
            result = result.AddYears(years).AddMonths(months).AddDays(days);
            return result;
        }
        /// <summary>
        /// 增加时、分数（对应位置传入负数即可减去对应数值）
        /// </summary>
        /// <param name="dateTime">计算前的日期时间对象</param>
        /// <param name="hours">时</param>
        /// <param name="minutes">分</param>
        /// <returns></returns>
        public static DateTime calculate(DateTime dateTime, int hours, int minutes)
        {
            DateTime result = new DateTime(dateTime.Year, dateTime.Month, dateTime.Day);
            result = result.AddHours(hours).AddMinutes(minutes);
            return result;
        }
        /// <summary>
        /// 增加秒数（传入负数即可减少秒数）
        /// </summary>
        /// <param name="dateTime">计算前的日期时间对象</param>
        /// <param name="seconds">秒</param>
        /// <returns></returns>
        public static DateTime calculate(DateTime dateTime, int seconds)
        {
            DateTime result = new DateTime(dateTime.Year, dateTime.Month, dateTime.Day);
            result = result.AddSeconds(seconds);
            return result;
        }
        /// <summary>
        /// 获取当月第一天（时分秒不变）
        /// </summary>
        /// <param name="dateTime">计算前的日期时间对象</param>
        /// <returns></returns>
        public static DateTime getFirstDayOfMonth(DateTime dateTime)
        {
            DateTime result = new DateTime(dateTime.Year, dateTime.Month, 1);
            return result;
        }
        /// <summary>
        /// 获取当月最后一天（时分秒不变）
        /// </summary>
        /// <param name="dateTime">计算前的日期时间对象</param>
        /// <returns></returns>
        public static DateTime getLastDayOfMonth(DateTime dateTime)
        {
            DateTime result = new DateTime(dateTime.Year, dateTime.Month, 1);
            result = result.AddMonths(1).AddDays(-1);
            return result;
        }

        #endregion
    }
}
